package br.com.sistema.dao;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import br.com.sistema.conexao.Entity;
import br.com.sistema.models.Entidade;
import br.com.sistema.models.EntidadeTipo;

public class PessoaDao implements IDao<Entidade> {

	/*public List<HashMap<String,Object>> convertResultSetToList(ResultSet rs) throws SQLException {
	    ResultSetMetaData md = rs.getMetaData();
	    int columns = md.getColumnCount();
	    List<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();

	    while (rs.next()) {
	        HashMap<String,Object> row = new HashMap<String, Object>(columns);
	        for(int i=1; i<=columns; ++i) {
	            row.put(md.getColumnName(i),rs.getObject(i));
	        }
	        list.add(row);
	    }
	    return list;
	}*/

	public Entidade getById(int id) throws Exception {
		return null;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<Entidade> getByCriteria(Entidade o) throws Exception {
		
		try {
			
			EntityManager em = Entity.createEm();
			List<Entidade> list;
			
			try {
				
				CriteriaBuilder cb = em.getCriteriaBuilder();
				CriteriaQuery c = cb.createQuery(Entidade.class);
				Root<Entidade> a = c.from(Entidade.class);
				c.select(a);
				
				//TODO: analisar o predicate
				List<Predicate> predicates = new ArrayList<Predicate>();
				
				if(o.getEntinome() != ""){
					predicates.add(cb.like(a.<String>get("entinome"), "%"+o.getEntinome()+"%"));
				}
				
				if(o.getEnticpfcnpj() != ""){
					predicates.add(cb.like(a.<String>get("enticpfcnpj"), "%"+o.getEnticpfcnpj()+"%"));
				}
				
				if(o.getEntisexo() != ""){
					predicates.add(cb.equal(a.<String>get("entisexo"), o.getEntisexo()));
				}
				
				if(o.getEntidadeTipo() != null){
					predicates.add(cb.equal(a.<EntidadeTipo>get("entidadeTipo"), o.getEntidadeTipo()));
				}
				
				c.where(cb.and(predicates.toArray(new Predicate[]{})));
				
				TypedQuery<Entidade> query = em.createQuery(c);
				list = query.getResultList();
				
				return list;

			} catch (Exception e) {
				throw e;
			}finally{
				em.close();
			}
		} catch (Exception e) {
			throw e;
		}
		
	}
	
	/*public List<Pessoa> getByCriteria(Pessoa o) throws Exception {
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet rs = null;
		List<Pessoa> list = new ArrayList<Pessoa>();
		try{
			
			String query = "select * ";
			query += " from entidade ";
			query += " where lower(enti_nome) like lower(?) and enti_cpf like ? and enti_sexo like ? and enti_tipo = 'F' ";
		    if(o.getEntidadeTipo() != null){
		    	query += " and enti_tipo_id = " + o.getEntidadeTipo().getEntiTipoId(); 
		    }
			query += " order by enti_nome";
			
			con = DataSource.getInstance().getConnection();
			stmt = con.prepareStatement(query);
			stmt.setString(1, "%" + o.getEntiNome() + "%");
			stmt.setString(2, "%" + o.getEntiCpf() + "%");
			stmt.setString(3, "%" + o.getEntiSexo() + "%");
			rs = stmt.executeQuery();
			while(rs.next()){
				Pessoa pf = new Pessoa();
				pf.setEntiId(Integer.parseInt(rs.getObject("enti_id").toString()));
				pf.setEntiNome(rs.getObject("enti_nome").toString());
				pf.setEntiCpf(rs.getObject("enti_cpf").toString());
				pf.setEntiSexo(rs.getObject("enti_sexo").toString());
				list.add(pf);
			}
			return list;
		} catch (Exception e) {
			throw e;
		} finally {
			try{
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(con != null) con.close();
			}catch(Exception e){
				throw e;
			}
		}
	}*/
	
	public void remove(List<Entidade> list) throws Exception {
		try{
			EntityManager em = Entity.createEm();
			try {
				
				em.getTransaction().begin();
				
				for(Entidade p : list){
					Entidade i = em.find(Entidade.class, p.getEntiid());
					em.remove(i);
				}
				
				list = null;
				
				em.getTransaction().commit();
				
			} catch (Exception e) {
				
				if(em.getTransaction().isActive()){
					em.getTransaction().rollback();
				}
				
				throw e;
				
			}finally{
				em.close();
			}
			
		}catch(Exception e){
			throw e;
		}
		
		/*Connection con = null;
		try {
			con = DataSource.getInstance().getConnection();
			con.setAutoCommit(false);
			for(Pessoa p : list){
				PreparedStatement stmt = con.prepareStatement("delete from entidade where enti_id = ?");
				stmt.setInt(1, p.getEntiId());
				stmt.executeUpdate();
				stmt.close();
			}
			con.commit();
		} catch (Exception e) {
			con.rollback();
			throw e;
		} finally {
			con.setAutoCommit(true);
			try{
				if(con != null) con.close();
			}catch(Exception e){
				throw e;
			}
		}*/
	}

	@Override
	public List<Entidade> getAll() throws Exception {
		return null;
	}

	@Override
	public Entidade manter(Entidade o) throws Exception {
		return null;
	}

	@Override
	public Entidade insere(Entidade o) throws Exception {
		try {
			EntityManager em = Entity.createEm();
			try {
				
				em.getTransaction().begin();
				em.persist(o);
				em.getTransaction().commit();
				
				return o;
				
			} catch (Exception e) {
				
				if(em.getTransaction().isActive()){
					em.getTransaction().rollback();
				}
				
				throw e;
				
			}finally{
				em.close();
			}
		} catch (Exception e) {
			throw e;
		}
	}

	@Override
	public Entidade altera(Entidade o) throws Exception {
		try {
			EntityManager em = Entity.createEm();
			try {
				
				em.getTransaction().begin();
				
				Entidade entidade = em.find(Entidade.class, o.getEntiid());
				entidade.setEntinome(o.getEntinome());
				entidade.setEnticpfcnpj(o.getEnticpfcnpj());
				entidade.setEntidadeTipo(o.getEntidadeTipo());
				entidade.setEntisexo(o.getEntisexo().toString());
				entidade.setEntidatanascimento(o.getEntidatanascimento());
				entidade.setEntinomepai(o.getEntinomepai());
				entidade.setEntinomemae(o.getEntinomemae());
				entidade.setEntiidentidade(o.getEntiidentidade());
				entidade.setEntiorgaoemissor(o.getEntiorgaoemissor());
				entidade.setEntidataemissao(o.getEntidataemissao());
				entidade.setEntinaturalidade(o.getEntinacionalidade());
				entidade.setEntinacionalidade(o.getEntinacionalidade());
				entidade.setEntiuf(o.getEntiuf());
				entidade.setEnticel1(o.getEnticel1());
				entidade.setEnticel2(o.getEnticel2());
				entidade.setEntiemail1(o.getEntiemail1());
				entidade.setEntiemail2(o.getEntiemail2());
				entidade.setEntitipo("F");
				entidade.setXusuario(o.getXusuario());
				em.persist(entidade);
				em.getTransaction().commit();
				
				return o;
				
			} catch (Exception e) {
				
				if(em.getTransaction().isActive()){
					em.getTransaction().rollback();
				}
				
				throw e;
				
			}finally{
				
				em.close();
				o=null;
				
			}
			
		} catch (Exception e) {
			throw e;
		}
	}
}
